package com.qd.panda.service.card.collect;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.cdqidi.constant.ConstantDto;
import com.cdqidi.exception.ApiException;
import com.qd.common.panda.domain.entity.card.collect.CollectCardDTO;
import com.qd.common.panda.domain.entity.card.collect.CollectCardRelationDTO;
import com.qd.common.panda.domain.entity.card.collect.ReceiveCardDTO;
import com.qd.common.sys.domain.login.LoginUser;
import com.qd.panda.model.CardInfo;
import com.qd.panda.model.CardPlan;
import com.qd.panda.model.CollectCard;
import com.qd.panda.model.CollectCardRelation;
import com.qd.panda.service.card.CardInfoService;
import com.qd.panda.service.card.CardPlanService;
import com.qd.system.service.person.AuthTokenService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.Optional;

/**
 * 〈一句话功能简述〉<br>
 *
 * @author sjk
 * @create 2023-09-22 15:24
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CollectCardHolderService {
    private final CollectCardService collectCardService;
    private final CollectCardRelationService collectCardRelationService;
    private final CardInfoService cardInfoService;
    private final AuthTokenService authTokenService;
    private final CardPlanService cardPlanService;
    @Resource
    private HttpServletRequest request;

    @Transactional(readOnly = true)
    public CollectCardDTO check(String cid, String promotionCode) {
        CollectCardDTO collectCard = Optional.ofNullable(collectCardService.getByIdDto(cid)).orElseThrow(() -> new ApiException("领劵ID值错误"));
        if (!collectCard.getPromotionCode().equals(promotionCode)) {
            throw new ApiException("推广码值错误");
        }
        return collectCard;
    }

    public void receiveCard(String userId, String mobile, ReceiveCardDTO dto) {
        CollectCardRelationDTO collectCardRelationDTO = Optional.ofNullable(collectCardRelationService.getByIdDto(dto.getRelationId())).orElseThrow(() -> new ApiException("关系ID值错误"));
        log.info("AvailableQuantity: {}", collectCardRelationDTO.getAvailableQuantity());
        if (collectCardRelationDTO.getAvailableQuantity() < 1) {
            throw new ApiException(10005, "券已发放完，下次再来哟！");
        }
        LocalDate currentDate = LocalDate.now();
        CardInfo cardInfo = Optional.ofNullable(cardInfoService.getById(collectCardRelationDTO.getCardMsgId())).orElseThrow(() -> new ApiException("券ID错误"));
        if (currentDate.isBefore(cardInfo.getUseStartTime())) {
            throw new ApiException("请在[" + cardInfo.getUseStartTime().toString() + "]开始兑换");
        }
        if (currentDate.isAfter(cardInfo.getUseEndTime())) {
            throw new ApiException("超过规定兑换时间，不能兑换");
        }
        collectCardRelationDTO.setAvailableQuantity(collectCardRelationDTO.getAvailableQuantity() - 1);
        collectCardService.receiveCard(userId, mobile, dto, collectCardRelationDTO);
        collectCardRelationDTO.freeData();
    }


    /**
     * 分页数据
     *
     * @param page 分页对象
     * @param dto  查询参数
     * @return 分页信息
     */
    @Transactional(readOnly = true)
    public IPage<CollectCardRelationDTO> page(Page<CollectCardRelation> page, CollectCardRelationDTO dto) {
        if (!StringUtils.hasLength(dto.getCid())) {
            if (!StringUtils.hasLength(dto.getPromotionCode())) {
                throw new ApiException("推广码不能为空");
            }
            CollectCardDTO collectCardDTO = collectCardService.getByPromotionCode(dto.getPromotionCode());
            log.info("promotionCode: {}", dto.getPromotionCode());
            if (null == collectCardDTO) {
                return new Page<>(page.getCurrent(), page.getSize(), 0);
            }
            dto.setCid(collectCardDTO.getCid());
        }
        return collectCardRelationService.page(page, dto);
    }

    /**
     * 判断是否已经领取
     * 没有信息的，返回true表示不需要领
     *
     * @param promotionCode
     * @param cid
     * @param now
     * @return
     */
    @Transactional(readOnly = true)
    public boolean existsCollectCard(String promotionCode, String cid, LocalDate now) {
        if (StringUtils.hasLength(promotionCode) && !StringUtils.hasLength(cid)) {
            CollectCardDTO collectCardDTO = collectCardService.getByPromotionCode(promotionCode);
            if (null == collectCardDTO) {
                //没有信息，说明不需要领
                log.info("根据推广码没有查询到信息");
                return true;
            } else {
                cid = collectCardDTO.getCid();
                log.info("cid为空，根据promotionCode查询到的cid: {},promotionCode: {}", cid, promotionCode);
            }
        }
        CollectCard collectCard = collectCardService.getById(cid);
        if (null == collectCard) {
            log.info("cid值错误: {}", cid);
            //没有信息，说明不需要领
            return true;
        }
        CardPlan cardPlan = cardPlanService.getById(collectCard.getPlanId());
        if (null == cardPlan) {
            log.info("planId为空,不需要领取: {}", collectCard.getPlanId());
            //没有信息，说明不需要领
            return true;
        }
        if (now.isBefore(cardPlan.getUseStartTime())) {
            //还未开始兑换，说明不需要领
            log.info("还未开始兑换,不需要领,now: {},startTime: {}", now, cardPlan.getUseStartTime());
            return true;
        }
        if (now.isAfter(cardPlan.getUseEndTime())) {
            //超过兑换时间，也说明不需要领
            log.info("超过兑换时间,不需要领,now: {},endTime: {}", now, cardPlan.getUseEndTime());
            return true;
        }
        if (cardPlan.getInfiniteQuantity().equals(ConstantDto.SF0)) {
            //如果不是无限数量的券需要验证是否有可以领取的券
            if (collectCardRelationService.availableQuantity(cid) < 1) {
                log.info("没有可以领取的卷,cid: {}", cid);
                return true;
            }
        }
        LoginUser loginUser = authTokenService.getLoginUser(request);
        if (null == loginUser) {
            //没用户的时候直接给false,three要求
            log.info("没有登录信息");
            return false;
        }
        Long count = collectCardRelationService.getBaseMapper().existsCollectCard(loginUser.getUserId(), promotionCode, cid, now);
        return SqlHelper.retBool(count);
    }
}